/* ID/EXE */

// Naming convention for wires into and out
// of this register should be [wirename]1

/* In/Out Parameters with # of bits: */
//
/* Parameters passed to next register: */
//    RegWrite = 1
//    RegWriteSrc = 2
//    MemWrite = 1
//    Jump = 2
//    JumpAddr = 32
//    Branch = 2
//    AdderA = 32
//    BusB = 32
/* Parameters used after this register: */
//    MemRead = 1
//    RegDst = 2
//    ALUSrc = 1
//    ALUCtr = 6
//    ExtOpt = 1
//    BusA = 32
//    InstructionIn = 32
//    Instruction15_0Out = 16
//    Instruction20_16Out = 5
//    Instruction15_11Out) = 5

module Decode_Execute(CLK,
                      RegWriteIn,
                      RegWriteOut,
                      RegWriteSrcIn,
                      RegWriteSrcOut,
                      MemReadIn,
                      MemReadOut,
                      MemWriteIn,
                      MemWriteOut,
                      JumpIn,
                      JumpOut,
                      BranchIn,
                      BranchOut,
                      RegDstIn,
                      RegDstOut,
                      ALUSrcIn,
                      ALUSrcOut,
                      ALUCtrIn,
                      ALUCtrOut, 
                      ExtOptIn,
                      ExtOptOut,
                      AdderAIn,
                      AdderAOut,
                      JumpAddrIn,
                      JumpAddrOut,
                      BusAIn, 
                      BusAOut,
                      BusBIn,
                      BusBOut,
                      InstructionIn,
                      Instruction15_0Out,
                      Instruction25_21Out,
                      Instruction20_16Out,
                      Instruction15_11Out,
                      Flush);
  input CLK,Flush;
  input RegWriteIn, MemReadIn, MemWriteIn, ALUSrcIn, ExtOptIn;
  input [1:0] RegWriteSrcIn, JumpIn, BranchIn, RegDstIn;
  input [5:0] ALUCtrIn;
  input [31:0] AdderAIn, JumpAddrIn, BusAIn, BusBIn, InstructionIn;

  output RegWriteOut, MemReadOut, MemWriteOut, ALUSrcOut, ExtOptOut;
  output [1:0] RegWriteSrcOut, JumpOut, BranchOut, RegDstOut;
  output [4:0] Instruction15_11Out, Instruction20_16Out, Instruction25_21Out;
  output [5:0] ALUCtrOut; 
  output [31:0] AdderAOut, JumpAddrOut, BusAOut, BusBOut;
  output [15:0] Instruction15_0Out;

  reg RegWriteOut, MemReadOut, MemWriteOut, ALUSrcOut, ExtOptOut;
  reg [1:0] RegWriteSrcOut, JumpOut, BranchOut, RegDstOut;
  reg [4:0] Instruction15_11Out, Instruction20_16Out, Instruction25_21Out;
  reg [5:0] ALUCtrOut; 
  reg [31:0] AdderAOut, JumpAddrOut, BusAOut, BusBOut;
  reg [15:0] Instruction15_0Out;
  
  always @(negedge CLK)
    if(Flush)
      begin
        RegWriteOut <= 0;
        RegWriteSrcOut <= 0;
        MemReadOut <= 0;
        MemWriteOut <= 0;
        JumpOut <= 0;
        BranchOut <= 0;
        $display($time, "  \n\nID/EX Flushed.\n\n");
      end
    else
      begin
        RegWriteOut <= RegWriteIn;
        RegWriteSrcOut <= RegWriteSrcIn;
        MemReadOut <= MemReadIn;
        MemWriteOut <= MemWriteIn;
        JumpOut <= JumpIn;
        BranchOut <= BranchIn;
        RegDstOut <= RegDstIn;
        ALUSrcOut <= ALUSrcIn;
        ALUCtrOut <= ALUCtrIn;
        ExtOptOut <= ExtOptIn;
        AdderAOut <= AdderAIn;
        JumpAddrOut <= JumpAddrIn;
        BusAOut <= BusAIn;
        BusBOut <= BusBIn; 
        Instruction15_0Out <= InstructionIn[15:0];
        Instruction25_21Out <= InstructionIn[25:21];
        Instruction20_16Out <= InstructionIn[20:16];
        Instruction15_11Out <= InstructionIn[15:11];
      end
endmodule
